package de.koller.reason.math;

import de.koller.oceanFramework.math.IProjection;
import de.koller.oceanFramework.math.RVec3;

public class IsometricProjection implements IProjection {

	public static final float O_S6 = 1f / (float)Math.sqrt( 6f );
	public static final float S3 = (float)Math.sqrt( 3f );
	public static final float S2 = (float)Math.sqrt( 2f );
	
	public static final float[] INVERSE = new float[] {
		 0.7071068f,  0.4082483f,  0.5773503f,
		 0f        ,  0.8164966f, -0.5773503f,
		-0.7071068f,  0.4082483f,  0.5773503f
	};
	
	public IsometricProjection() {}

	@Override
	public RVec3 project( RVec3 v, RVec3 result ) {
		return result.set( 
				O_S6 * ( S3*v.x - S3*v.z ), 
				O_S6 * ( v.x + 2*v.y + v.z ), 
				O_S6 * ( S2*v.x - S2*v.y + S2*v.z ) 
			);
	}
	
	@Override
	public RVec3 unproject( RVec3 v, RVec3 result ) {
		return result.set(
				INVERSE[0]*v.x + INVERSE[1]*v.y + INVERSE[2]*v.z,
				INVERSE[3]*v.x + INVERSE[4]*v.y + INVERSE[5]*v.z,
				INVERSE[6]*v.x + INVERSE[7]*v.y + INVERSE[8]*v.z
			);
	}
	
}
